﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ElevatorSimCSharp
{
    class Interactions
    {
		public static void everything(Building building) {
			Elevator[] elevators = building.getElevators();
			foreach (Elevator elevator in elevators) {
				switch (elevator.getState()) {
				case ElevatorState.ElevatorMoving:
					elevator.incrementPosition();
					break;
				case ElevatorState.DoorOpening:
					elevator.incrementDoorOpening();
					break;
					
				case ElevatorState.DoorOpenPeopleExit:
					Floor floor = building.getFloor(elevator.getCurrentFloor());
					incrementMovePeopleFromElevatorToFloor(floor, elevator);
					break;
					
				case ElevatorState.DoorOpenPeopleEnter:
					incrementMovePeopleFromFloorToElevator(floor, elevator);
					break;
					
				case ElevatorState.DoorClosing:
					elevator.decrementDoorClosing();
					break;
					
				
				case ElevatorState.Idle:
					break;
				}
			}
		}

		public static void incrementMovePeopleFromElevatorToFloor (Floor floor, Elevator elevator)
		{
			elevator.incrementTime();
		}
		
		inc
		
		
		
		
		
		
		
		
		
		
        public static void movePeopleToElevator(Building building)
        {
            Elevator[] elevatorArray = building.getElevators();
            foreach (Elevator elevator in elevatorArray)
            {
				if (elevator.getState() == ElevatorState.DoorOpen) 
                short currentFloor = elevator.getCurrentFloor();
                sbyte direction = elevator.getDirection();
                List<Person> elevatorPeople = elevator.getPersonsList();
                List<Person> removePeopleFromElevator = new List<Person>();
                foreach (Person person in elevatorPeople)
                {
                    if (currentFloor == person.getWantToGoTo())
                    {
                        removePeopleFromElevator.Add(person);
                        elevator.decrementNumberOfPeopleInElevator();
                        Person.numberOfPeopleWhoveTakenElevator++;
                    }
                }
                foreach (Person person in removePeopleFromElevator)
                {
                    elevatorPeople.Remove(person);
                }
                elevator.setPersonsList(elevatorPeople);

                List<Person> floorPeople = building.getCurrentFloorPeopleList(elevator.getCurrentFloor());
                List<Person> removeFromFloor = new List<Person>();

                
                foreach (Person person in floorPeople)
                {
                    if (elevator.getNumberOfPeopleInElevator() < elevator.getMaxNumberOfPeople())
                    {
                        if (person.getWantToGoTo() - elevator.getCurrentFloor() > 0 && direction >= 0)
                        {
                            elevator.incrementNumberOfPeopleInElevator();
                            elevator.addPerson(person);
                            removeFromFloor.Add(person);
                        }
                        else if (person.getWantToGoTo() - elevator.getCurrentFloor() < 0 && direction <= 0)
                        {
                            elevator.incrementNumberOfPeopleInElevator();
                            elevator.addPerson(person);
                            removeFromFloor.Add(person);
                        }
                    }
                    else break;
                }
                foreach (Person person in removeFromFloor)
                {
                    floorPeople.Remove(person);
                }
            }
            
        }

        public static void createRandomPerson(Building building)
        {
            Random random = new Random();
            if (random.Next(0, 10) >= 8)
            {
                Person person = new Person();
                short floor = (short)random.Next((int)building.getLowestFloor(), (int)building.getHighestFloor());
                do
                {
                    person.setWantToGoTo((byte)random.Next(building.getLowestFloor(), building.getHighestFloor()));
                } while (person.getWantToGoTo() == floor);
                building.putPersonOnFloor(person, floor);
            }
        }

        public static void findLastFloorToGoTo(Elevator[] elevators, Floor[] floors) {
            foreach (Elevator elevator in elevators) {
                List<Person> people = elevator.getPersonsList();
                if (elevator.getDirection() > 0) {
                    short highestFloor = elevator.getLastFloorToGoTo();
                    foreach (Person person in people) {
                        if (person.getWantToGoTo() > elevator.getLastFloorToGoTo()) {
                            highestFloor = person.getWantToGoTo();
                        }
                    }
                    short highestFloorWithPeople = Interactions.checkFloorsForPeopleAboveElevator(floors, elevator);
                    if (highestFloor > highestFloorWithPeople) {
                            elevator.setLastFloorToGoTo(highestFloor);
                    }
                    else {
                        elevator.setLastFloorToGoTo(highestFloorWithPeople);
                    }
                }
                else {
                    short lowestFloor = elevator.getLastFloorToGoTo();
                    foreach (Person person in people) {
                        if (person.getWantToGoTo() < elevator.getLastFloorToGoTo()) {
                            lowestFloor = person.getWantToGoTo();
                        }
                    }
                    short lowestFloorWithPeople = Interactions.checkFloorsForPeopleBelowElevator(floors, elevator);
                    if (lowestFloor > lowestFloorWithPeople) {
                            elevator.setLastFloorToGoTo(lowestFloor);
                    }
                    else {
                        elevator.setLastFloorToGoTo(lowestFloorWithPeople);
                    }
                }
            }
        }


        //public static short findLastFloorToGoTo(Floor[] floors, short checkFrom, short checkToo, sbyte direction)
        //{
        //    short lastFloorToGoTo = null;
        //    for (int i = checkFrom; i != checkToo; i += direction)
        //    {
        //        List<Person> people = floors[i].getPersonsList();
        //        foreach (Person person in people)
        //        {
        //            if (person.getWantToGoTo() == 0) { }
        //        }
        //    }
        //}


        public static void moveElevators(Building building)
        {
            Elevator[] elevators = building.getElevators();
            foreach(Elevator elevator in elevators) {
				if (elevator.getState() == ElevatorState.ElevatorMoving) {
					elevator.moveElevator(elevator.getDirection());
					if (building.getFloor(elevator.getCurrentFloor()).getUpButton() == true && elevator.getDirection() > 0) {
						elevator.setState(ElevatorState.DoorOpening);
					}
					else if (building.getFloor(elevator.getCurrentFloor()).getDownButton() == true && elevator.getDirection() < 0) {
						elevator.setState(ElevatorState.DoorOpening);
					}
				}	
            }
        }

        //private short checkForPeopleWantingToGoUpOverCurrentFloor(Floor[] floors, short currentFloor) {
        //    short highestFloorToGoTo = 0;
        //    for (int i = floors.Length-1; i > currentFloor; i--) {
        //        List<Person> people = floors[i].getPersonsList();
        //        foreach(Person person in people) {
        //            if (person.getWantToGoTo() > highestFloorToGoTo) {
        //                highestFloorToGoTo= person.getWantToGoTo();
        //            }
        //        }
        //    }
        //    return highestFloorToGoTo;
        //}

        public static short checkFloorsForPeopleAboveElevator(Floor[] floors, Elevator elevator) {
            short highestFloor = elevator.getCurrentFloor();
            for (int i = floors.Length-1; i > elevator.getCurrentFloor(); i--) {
                List<Person> people = floors[i].getPersonsList();
                if (people.Count() != 0)  {
                    highestFloor = (short) i;
                    break;
                }
            }
            List<Person> peopleElevator = elevator.getPersonsList();
            foreach (Person person in peopleElevator)
            {
                if (person.getWantToGoTo() > highestFloor)
                {
                    highestFloor = person.getWantToGoTo();
                }
            }
            if (elevator.getCurrentFloor() != highestFloor)
            {
                return highestFloor;
            }
            return elevator.getCurrentFloor();
        }

        public static short checkFloorsForPeopleBelowElevator(Floor[] floors, Elevator elevator) {
            short lowestFloor = elevator.getCurrentFloor();
            for (int i = 0; i < elevator.getCurrentFloor(); i++) {
                List<Person> people = floors[i].getPersonsList();
                if (people.Count() != 0)  {
                    lowestFloor = (short) i;
                    break;
                }
            }
            List<Person> peopleElevator = elevator.getPersonsList();
            foreach (Person person in peopleElevator)
            {
                if (person.getWantToGoTo() < lowestFloor)
                {
                    lowestFloor = person.getWantToGoTo();
                }
            }
            if (elevator.getCurrentFloor() != lowestFloor)
            {
                return lowestFloor;
            }
            return elevator.getCurrentFloor();
        }

        public static void changeDirectionElevator(Floor[] floors, Elevator[] elevators) {
            foreach (Elevator elevator in elevators) {
                if (elevator.getDirection() > 0) {
                    elevator.setLastFloorToGoTo(Interactions.checkFloorsForPeopleAboveElevator(floors, elevator));
                    
                    if (elevator.getCurrentFloor() == elevator.getLastFloorToGoTo()) {
                        elevator.setLastFloorToGoTo(Interactions.checkFloorsForPeopleBelowElevator(floors, elevator));
                        if (elevator.getCurrentFloor() == elevator.getLastFloorToGoTo()) {
                            elevator.setDirection(0);
                        }
                        else {
                            elevator.setDirection(-1);
                        }
                    }
                }
                else if (elevator.getDirection() < 0) {
                    elevator.setLastFloorToGoTo(Interactions.checkFloorsForPeopleBelowElevator(floors, elevator));
                    if (elevator.getLastFloorToGoTo() == elevator.getCurrentFloor()){
                        elevator.setLastFloorToGoTo(Interactions.checkFloorsForPeopleAboveElevator(floors, elevator));
                        if (elevator.getCurrentFloor() == elevator.getLastFloorToGoTo()) {
                            elevator.setDirection(0);
                        }
                        else {
                            elevator.setDirection(1);
                        }
                    }
                }
                else {
                    if (elevator.getCurrentFloor() < floors.Length/2) {
                        elevator.setLastFloorToGoTo(Interactions.checkFloorsForPeopleBelowElevator(floors, elevator));
                        if (elevator.getCurrentFloor() == elevator.getLastFloorToGoTo()) {
                            elevator.setLastFloorToGoTo(Interactions.checkFloorsForPeopleAboveElevator(floors, elevator));
                            if (elevator.getCurrentFloor() != elevator.getLastFloorToGoTo()) {
                                elevator.setDirection(1);
                            }
                        }
                        else {
                            elevator.setDirection(-1);
                        }
                    }

                    else {
                        elevator.setLastFloorToGoTo(Interactions.checkFloorsForPeopleAboveElevator(floors, elevator));
                        if (elevator.getCurrentFloor() == elevator.getLastFloorToGoTo()) {
                            elevator.setLastFloorToGoTo(Interactions.checkFloorsForPeopleBelowElevator(floors, elevator));
                            if (elevator.getCurrentFloor() != elevator.getLastFloorToGoTo()) {
                                elevator.setDirection(-1);
                            }
                        }
                        else {
                            elevator.setDirection(1);
                        }
                    }
                }
            }
        }
    }
}

